﻿// ***********************************************************************
// Assembly         : INNOVACALL.Framework.Common
// Author           : LJO+01 (Laurent Jordi)
// Created          : 06-05-2013
// Last Modified By : LJO+01 (Laurent Jordi)
// Last Modified On : 06-05-2013
// ***********************************************************************
// <copyright file="SerializableList.cs" company="Copyright © Innovacall 2011">
//     Copyright (c) Copyright © Innovacall 2011. All rights reserved.
// </copyright>
// <summary></summary>
// ***********************************************************************
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Xml.Serialization;

namespace INNOVACALL.Framework.Common.Serialization
{
    /// <summary>
    /// Class SerializableList
    /// </summary>
    /// <typeparam name="T"></typeparam>
    [XmlRoot("list")]
    [Serializable]
    public class SerializableList<T> : List<T>, IXmlSerializable
    {

        #region "Contructors"
        /// <summary>
        /// Initializes a new instance of the <see cref="SerializableList{T}"/> class.
        /// </summary>
        public SerializableList() : base() { }
        /// <summary>
        /// Initializes a new instance of the <see cref="SerializableList{T}"/> class.
        /// </summary>
        /// <param name="list">The list.</param>
        public SerializableList(IList<T> list) : base(list) { }
        /// <summary>
        /// Initializes a new instance of the <see cref="T:System.Collections.Generic.List`1" /> class that is empty and has the specified initial capacity.
        /// </summary>
        /// <param name="capacity">The number of elements that the new list can initially store.</param>
        public SerializableList(int capacity) : base(capacity) { }
        /// <summary>
        /// Initializes a new instance of the <see cref="SerializableList{T}"/> class.
        /// </summary>
        /// <param name="info">The info.</param>
        /// <param name="context">The context.</param>
        protected SerializableList(SerializationInfo info, StreamingContext context) { }
        #endregion
        #region IXmlSerializable Members
        /// <summary>
        /// Cette méthode est réservée et ne doit pas être utilisée.Lorsque vous implémentez l'interface IXmlSerializable, vous devez retourner la valeur null (Nothing dans Visual Basic) à partir cette méthode et, si la spécification d'un schéma personnalisé est requise, appliquez à la place <see cref="T:System.Xml.Serialization.XmlSchemaProviderAttribute" /> à la classe.
        /// </summary>
        /// <returns><see cref="T:System.Xml.Schema.XmlSchema" /> qui décrit la représentation XML de l'objet qui est généré par la méthode <see cref="M:System.Xml.Serialization.IXmlSerializable.WriteXml(System.Xml.XmlWriter)" /> et utilisé par la méthode <see cref="M:System.Xml.Serialization.IXmlSerializable.ReadXml(System.Xml.XmlReader)" />.</returns>
        public System.Xml.Schema.XmlSchema GetSchema()
        {
            return null;
        }
        /// <summary>
        /// Génère un objet à partir de sa représentation XML.
        /// </summary>
        /// <param name="reader"><see cref="T:System.Xml.XmlReader" /> source à partir de laquelle l'objet est désérialisé.</param>
        public void ReadXml(System.Xml.XmlReader reader)
        {
            XmlSerializer itemSerializer = new XmlSerializer(typeof(T));

            bool wasEmpty = reader.IsEmptyElement;
            reader.Read();

            if (wasEmpty)
                return;

            while (reader.NodeType != System.Xml.XmlNodeType.EndElement)
            {
                reader.ReadStartElement("item");
                T item = (T)itemSerializer.Deserialize(reader);
                reader.ReadEndElement();

                this.Add(item);

                //reader.ReadEndElement();
                reader.MoveToContent();
            }
            reader.ReadEndElement();
        }
        /// <summary>
        /// Convertit un objet en sa représentation XML.
        /// </summary>
        /// <param name="writer"><see cref="T:System.Xml.XmlWriter" /> flux dans lequel l'objet est sérialisé.</param>
        public void WriteXml(System.Xml.XmlWriter writer)
        {
            XmlSerializer itemSerializer = new XmlSerializer(typeof(T));

            foreach (T item in this)
            {
                writer.WriteStartElement("item");
                itemSerializer.Serialize(writer, item);
                writer.WriteEndElement();
            }
        }
        #endregion

        /// <summary>
        /// Gets the type of the element.
        /// </summary>
        /// <value>The type of the element.</value>
        public Type ElementType
        {
            get { return this.AsQueryable<T>().ElementType; }
        }

        /// <summary>
        /// Gets the expression.
        /// </summary>
        /// <value>The expression.</value>
        public System.Linq.Expressions.Expression Expression
        {
            get { return this.AsQueryable<T>().Expression; }

        }

        /// <summary>
        /// Gets the provider.
        /// </summary>
        /// <value>The provider.</value>
        public IQueryProvider Provider
        {
            get { return this.AsQueryable<T>().Provider; }

        }
    }
}
